<?php
namespace addon\wechat_config\controller;

use tpfcore\Core;
use app\common\controller\AddonBase;
use tpfcore\wxbizmsgcrypt\WXBizMsgCrypt;
use addon\wechat_fans\logic\WechatRequest;

class Receive extends AddonBase
{
	public function _initialize(){
		parent::_initialize();
        self::initWechatConst();
		isset($this->param['echostr']) && self::valid();
	}

	public function index(){

        $XmlStr = file_get_contents('php://input');
        if(empty($XmlStr)){
            $this->err_log('XML原数据为空',$XmlStr);
            die('');
        }
        $wxparam = $this->param;
        if(!empty($wxparam) && is_array($wxparam)){
            try {
                $timestamp     = $wxparam['timestamp'];
                $nonce         = $wxparam['nonce'];
                $msg_signature = isset($wxparam['msg_signature'])?$wxparam['msg_signature']:'';
                
                $wechatEncode = new WXBizMsgCrypt(WECHAT_TOKEN,WECHAT_ENCODINGAESKEY,WECHAT_APPID);
                $decryptMsg   = '';  //解密后的明文
                $errCode      = $wechatEncode->decryptMsg($msg_signature,$timestamp,$nonce,$XmlStr,$decryptMsg);
                $XmlStr       = $decryptMsg;
                if($errCode != 0){
                    $this->err_log('解密失败',$errCode);
                }
            } catch (\Exception $e) {
                $this->err_log('解密异常',$e->getMessage());
            }

            $wx_log = 'timestamp:'.$timestamp.'=nonce:'.$nonce.'=msg_signature:'.$msg_signature;
            $this->wechat_log('额外数据：',$wx_log);
        }

        $encrypt_type  = (isset($wxparam['encrypt_type']) && ($wxparam['encrypt_type'] =='aes'))?'aes':'raw';

        $this->wechat_log('加密类型',$encrypt_type);
        file_put_contents('wechat_param.txt','处理后数据：'.$XmlStr.PHP_EOL,FILE_APPEND);

		$XmlObj = simplexml_load_string($XmlStr, 'SimpleXMLElement', LIBXML_NOCDATA);

        //写入请求日志,未安装插件的时候会出问题
        (new WechatRequest())->weChatRequestLog($XmlObj,$XmlStr);

        $this->wechat_log('事件类型',$XmlObj->MsgType);
        try {
            switch ($XmlObj->MsgType) {
                case 'event':
                    $result = Core::loadAddonModel('ReceiveEvent')->receiveEventFunc($XmlObj);
                    break;
                case 'text':
                    $result = Core::loadAddonModel('ReceiveText')->receiveTextFunc($XmlObj);
                    break;
                case 'location':
                case 'image':
                case 'voice':
                case 'video':
                case 'link':
                    $func   = 'receive' . ucfirst($XmlObj->MsgType) . 'Func';
                    $result = Core::loadAddonModel('WechatReceive')->$func($XmlObj);
                    break;
                default:
                    $result = 'unknown msg type: '.$XmlObj->MsgType;
                    break;
            }
            if ($encrypt_type == 'aes'){

                $wechatEncode = new WXBizMsgCrypt(WECHAT_TOKEN,WECHAT_ENCODINGAESKEY,WECHAT_APPID);
                $encryptMsg   = '';
                $errCode      = $wechatEncode->encryptMsg($result, $timestamp, $nonce, $encryptMsg);
                $result       = $encryptMsg;
                if($errCode != 0){
                    $this->err_log('加密失败',$errCode);
                }
            }
            die($result);
        } catch (\Exception $e) {
            $this->err_log('程序错误',$e->getMessage());
        }
        die('');
	}

	//验证签名
   	protected function valid(){

		$echoStr   = $this->param['echostr'];
		$signature = $this->param['signature'];
		$timestamp = $this->param['timestamp'];
		$nonce     = $this->param['nonce'];
		$token     = WECHAT_TOKEN;
		$tmpArr    = array($token, $timestamp, $nonce);

        sort($tmpArr, SORT_STRING);
        $tmpStr = sha1(implode($tmpArr));

        if($tmpStr == $signature){
            file_put_contents('wechat_check.txt','验证成功,时间：'.date('Y-m-d H:i:s').'----随机串：'.$echoStr.PHP_EOL,FILE_APPEND);
            die($echoStr);
        }
        file_put_contents('wechat_check.txt','验证失败,时间：'.date('Y-m-d H:i:s').'----随机串：'.$echoStr.PHP_EOL,FILE_APPEND);
    }

    private function initWechatConst(){
        
        $data   = \think\Db::name('WechatConfig')->order('id desc')->find();
        $config = json_decode($data['value'],true);
        $auto_reply      = json_decode($data['auto_reply'],true);//消息回复配置
        $subscribe_reply = json_decode($data['subscribe_reply'],true);//关注回复配置

        //if(empty($config) || empty($auto_reply) || empty($subscribe_reply)){
        if(empty($config)){
            die('配置不完整');
        }
        if($auto_reply){
            foreach ($auto_reply as $key => $value) {
                define(strtoupper($key),$value);
                //WECHAT_AUTO_MSG_TYPE
                //WECHAT_AUTO_MSG_VALUE
                //WECHAT_AUTO_MSG_TEXT
            }
        }
        if($subscribe_reply){
            foreach ($subscribe_reply as $key => $value) {
                define(strtoupper($key),$value);
                //WECHAT_SUBSCRIBE_MSG_TYPE
                //WECHAT_SUBSCRIBE_MSG_VALUE
                //WECHAT_SUBSCRIBE_MSG_TEXT
            }
        }
        define('WECHAT_NAME', $config['wechat_name']);//公众号名字
        define('WECHAT_TOKEN', $config['wechat_token']);//令牌(Token)
        define('WECHAT_APPID', $config['wechat_appid']);//AppID
        define('WECHAT_NUMBER', $config['wechat_no']);//公众号微信号
        define('WECHAT_ROBOT_ON', $config['wechat_robot_on']);//是否开启机器人
        define('WECHAT_ENCODINGAESKEY', $config['wechat_encodingaeskey']);//消息加解密密钥
        define('TO_KF_KEYWORD',$config['to_kf_keyword']);//转发客服系统触发词
    }

    protected function err_log($msg='异常',$errCode=''){
        file_put_contents('wechat_error.txt','时间：'.date('Y-m-d H:i:s').'='.$msg.':'.$errCode.PHP_EOL,FILE_APPEND);
    }
    protected function wechat_log($msg='操作记录',$data=''){
        file_put_contents('wechat_log.txt','时间：'.date('Y-m-d H:i:s').'='.$msg.':'.$data.PHP_EOL,FILE_APPEND);
    }
}